/**
 * Copyright (c) 2005-2006, David A. Czarnecki
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 * Neither the name of the "David A. Czarnecki" nor the names of
 * its contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Products derived from this software may not be called "PosterClient Java API",
 * nor may "PosterClient Java API" appear in their name, without prior written permission of
 * David A. Czarnecki.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.tianbing.adlottery.helper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.log4j.Logger;

/**
 * Akistmet Java API
 * <p>
 * </p>
 * refer to <a href="http://akismet.com/development/api/">PosterClient API</a>
 * documentation.
 * 
 * @author Conan Chan
 * @version $Id: PosterClient.java,v 1.4 2006/08/06 20:10:00 czarneckid Exp $
 */
public class WebSiteHttpClient {

	static Logger logger = Logger.getLogger(WebSiteHttpClient.class);

	// Constants

	private static final String USER_AGENT_HEADER = "User-Agent";

	private static final String USER_AGENT_VALUE = "PosterClient Java API/1.02";

	private static final String API_PARAMETER_KEY = "key";

	private static final String VALID_RESPONSE = "valid";

	private static final String FALSE_RESPONSE = "false";

	private HttpClient httpClient;

	private String apiKey = "111";

	private boolean verifiedKey = false;

	private int httpResult;

	public WebSiteHttpClient() {
		httpClient = new HttpClient();
		HttpClientParams httpClientParams = new HttpClientParams();
		DefaultHttpMethodRetryHandler defaultHttpMethodRetryHandler = new DefaultHttpMethodRetryHandler(0, false);
		httpClientParams.setParameter(USER_AGENT_HEADER, USER_AGENT_VALUE);
		httpClientParams.setParameter(HttpClientParams.RETRY_HANDLER, defaultHttpMethodRetryHandler);
		httpClient.setParams(httpClientParams);
	}

	/**
	 * Construct an instance to work with the PosterClient API.
	 * <p>
	 * </p>
	 * 
	 * <pre>
	 *      Usage:
	 *      &lt;p/&gt;
	 *      PosterClient akismet = new PosterClient(&quot;Your API key&quot;, &quot;http://your.blog.com/&quot;);
	 *      System.out.println(&quot;Testing comment spam: &quot; + akismet.commentCheck(&quot;x.y.z.w&quot;, &quot;XXX&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;VIAGRA! LOTS OF VIAGRA!&quot;, null));
	 * </pre>
	 * 
	 * <p>
	 * You <strong>do not</strong> need to call {@link #verifyAPIKey()} before
	 * using the
	 * {@link #commentCheck(String, String, String, String, String, String, String, String, String, java.util.Map)},
	 * {@link #submitSpam(String, String, String, String, String, String, String, String, String, java.util.Map)},
	 * or
	 * {@link #submitHam(String, String, String, String, String, String, String, String, String, java.util.Map)}
	 * methods.
	 * </p>
	 * 
	 * @param apiKey
	 *            PosterClient API key
	 * @param blog
	 *            Blog associated with the API key
	 * @throws IllegalArgumentException
	 *             If either the API key or blog is <code>null</code>
	 */
	public WebSiteHttpClient(String apiKey) {
		this.apiKey = apiKey;

		if (apiKey == null) {
			throw new IllegalArgumentException("API key cannot be null");
		}

	}

	/**
	 * Return the HTTP status code of the last operation
	 * 
	 * @return HTTP status code
	 */
	public int getHttpResult() {
		return httpResult;
	}

	/**
	 * Check to see if the API key has been verified
	 * 
	 * @return <code>true</code> if the API key has been verified,
	 *         <code>false</code> otherwise
	 */
	public boolean isVerifiedKey() {
		return verifiedKey;
	}

	/**
	 * Sets proxy configuration information. This method must be called before
	 * any calls to the API if you require proxy configuration.
	 * 
	 * @param proxyHost
	 *            Proxy host
	 * @param proxyPort
	 *            Proxy port
	 */
	private void setProxyConfiguration(String proxyHost, int proxyPort) {
		HostConfiguration hostConfiguration = new HostConfiguration();
		hostConfiguration.setProxy(proxyHost, proxyPort);

		httpClient.setHostConfiguration(hostConfiguration);
	}

	/**
	 * Check to see if the input is <code>null</code> or blank
	 * 
	 * @param input
	 *            Input
	 * @return <code>true</code> if input is null or blank, <code>false</code>
	 *         otherwise
	 */
	private boolean checkNullOrBlank(String input) {
		return (input == null || "".equals(input));
	}

	/**
	 * Sets proxy authentication information. This method must be called before
	 * any calls to the API if you require proxy authentication.
	 * 
	 * @param proxyUsername
	 *            Username to access proxy
	 * @param proxyPassword
	 *            Password to access proxy
	 */
	private void setProxyAuthenticationConfiguration(String proxyUsername, String proxyPassword) {
		httpClient.getState().setProxyCredentials(AuthScope.ANY,
				new UsernamePasswordCredentials(proxyUsername, proxyPassword));
	}

	/**
	 * Verify your API key
	 * 
	 * @return <code>true</code> if the API key has been verified,
	 *         <code>false</code> otherwise
	 */
	public boolean verifyAPIKey() {
		boolean callResult = true;

		PostMethod post = new PostMethod("http://rest.akismet.com/1.1/verify-key");
		post.addParameter(API_PARAMETER_KEY, apiKey);

		try {
			httpResult = httpClient.executeMethod(post);
			String result = post.getResponseBodyAsString();

			if (logger.isDebugEnabled()) {
				logger.debug("PosterClient response: " + result);
			}

			if (!checkNullOrBlank(result)) {
				if (!VALID_RESPONSE.equals(result)) {
					callResult = false;
				}
			}
		} catch (IOException e) {
			logger.error(e);
			callResult = false;
		}

		verifiedKey = callResult;

		return callResult;
	}

	@SuppressWarnings("finally")
	public String getterCall(String getUrl) {
		String result = "", s = "";
		GetMethod getMethod = new GetMethod(getUrl);
		// InputStream is = null;
		BufferedReader reader = null;
		try {
			httpResult = httpClient.executeMethod(getMethod);
			// is = getMethod.getResponseBodyAsStream();
			reader = new BufferedReader(new InputStreamReader(getMethod.getResponseBodyAsStream(), getMethod
					.getResponseCharSet()));
			// stdInput = new BufferedReader(new InputStreamReader(is,
			// "GB2312"));
			// read the output from the command
			while ((s = reader.readLine()) != null) {
				// logger.info(s);
				result += s;
			}
		} catch (HttpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			getMethod.releaseConnection();
			return result;
		}
	}

	public boolean posterCall(String posterUrl, Map<String, String> params) {
		boolean callResult = false;

		String akismetURL = posterUrl;

		PostMethod post = new PostMethod(akismetURL);
		post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");

		if (params != null && params.size() > 0) {
			Iterator<String> keyIterator = params.keySet().iterator();
			while (keyIterator.hasNext()) {
				String key = keyIterator.next();
				if ((key != null) && (params.get(key) != null)) {
					post.addParameter(new NameValuePair(key, params.get(key).toString()));
				}
			}
		}

		try {
			httpResult = httpClient.executeMethod(post);
			String result = post.getResponseBodyAsString();

			if (logger.isDebugEnabled()) {
				logger.debug("PosterClient response: " + result);
			}

			if (!checkNullOrBlank(result)) {
				result = result.trim();

				if (!FALSE_RESPONSE.equals(result)) {
					callResult = true;
				}
			}
		} catch (IOException e) {
			logger.error(e);
			callResult = true;
		}

		return callResult;
	}

	public void setApiKey(String apiKey) {
		this.apiKey = apiKey;
	}

	public static void main(String[] args) throws Exception {
		WebSiteHttpClient wsClient = new WebSiteHttpClient("key111");
		wsClient.getterCall("http://www.eetchina.com");
	}
}
